package com.yindian.cos.easy.security.authentication.verify;

import com.yindian.cos.easy.security.authentication.token.Token;
import com.yindian.cos.easy.security.authentication.token.TokenStore;
import com.yindian.cos.easy.security.exception.AccessTokenInvalidException;
import com.yindian.cos.easy.security.exception.AuthenticationException;
import com.yindian.cos.easy.security.exception.NullAccessTokenException;
import com.yindian.cos.easy.security.properties.EasySecurityProperties;
import com.yindian.cos.easy.security.properties.TokenVerifyProperties;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * token拦截器
 *
 * @author zhangchuanhao
 * @create 2018/11/22
 */
@Log4j2
public class TokenVerifyAuthentication extends AbstractVerifyAuthentication {

    private final EasySecurityProperties easySecurityProperties;

    private final TokenStore tokenStore;

    public TokenVerifyAuthentication(EasySecurityProperties easySecurityProperties, TokenStore tokenStore) {
        this.easySecurityProperties = easySecurityProperties;
        this.tokenStore = tokenStore;
    }

    @Override
    public void verify(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        String accessToken = request.getHeader(easySecurityProperties.getTokenVerify().getTokenKey());
        String url = request.getRequestURI();
        verify(url, accessToken);
    }

    public void verify(String url, String accessToken) {
        TokenVerifyProperties tokenVerifyProperties = easySecurityProperties.getTokenVerify();
        String[] exclusions = tokenVerifyProperties.getExclusions();
        if (!interceptOrPass(exclusions, url)) {
            if (StringUtils.isBlank(accessToken)) {
                throw new NullAccessTokenException("header中未发现access token");
            }
            Token token = tokenStore.getTokenByAccessToken(accessToken);
            boolean flag = tokenStore.isAccessTokenNonExpired(token);
            if (flag) {
                throw new AccessTokenInvalidException("access token已过期，accessToken = " + accessToken);
            }
        }
    }

    @Override
    public boolean next(HttpServletRequest request) {
        return false;
    }

    @Override
    public boolean support(HttpServletRequest request) {
        TokenVerifyProperties tokenVerifyProperties = easySecurityProperties.getTokenVerify();
        String[] includes = tokenVerifyProperties.getIncludes();
        boolean flag = interceptOrPass(includes, request.getRequestURI());
        if (flag) {
            log.debug("执行拦截过滤器{}", this.getClass().getSimpleName());
        }
        return flag;
    }

    @Override
    public int order() {
        return easySecurityProperties.getTokenVerify().getOrder();
    }
}
